// http客户端
#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/HttpUtil.h>
#include <signal.h>
#include <iostream>
using std::cout;
using std::cerr;
static WFFacilities::WaitGroup waitGroup(1);
void sighandler(int signum){
	//保证主线程不结束，等待执行
    waitGroup.done();
    cout << "done\n";
}

void httpCallback(WFHttpTask *task){
	//获取请求报文以及回复报文
	protocol::HttpRequest *req = task->get_req();
	protocol::HttpResponse *resp = task->get_resp(); 
	//获取状态
	int state = task->get_state();
	int error = task->get_error();

	switch(state){
	case WFT_STATE_SYS_ERROR:
		cerr <<"system error: " << strerror(error) << "\n";
		break;
	case WFT_STATE_DNS_ERROR:
		cerr <<"DNS error: " << gai_strerror(error) << "\n";
		break;
	case WFT_STATE_SSL_ERROR:
		cerr <<"SSL error: " << error << "\n";
		break;
	case WFT_STATE_TASK_ERROR:
		cerr <<"Task error: "<< error << "\n";
		break;
	case WFT_STATE_SUCCESS:
		break;
	}
	if (state != WFT_STATE_SUCCESS){
		cerr <<"Failed. Press Ctrl-C to exit.\n";
		return;
	}
	//解析请求报文
	cerr << req->get_method() << " "
		 << req->get_http_version() << " "
	     << req->get_request_uri() << "\n";
	protocol::HttpHeaderCursor reqCursor(req);
	std::string name;
	std::string value;
	while (reqCursor.next(name, value)){
        cerr << "name = " << name << " value = " << value << "\n";
    }

	//解析回复报文
	cerr << resp->get_http_version() << " "
		 << resp->get_status_code()  << " "
		 << resp->get_reason_phrase() << "\n";
	protocol::HttpHeaderCursor respCursor(resp);
	while (respCursor.next(name, value)){
        cerr << "name = " << name << " value = " << value << "\n";
    }

	//获取响应体
	const void *body;
	size_t body_len;
	resp->get_parsed_body(&body, &body_len);
    cerr << static_cast<const char *>(body) << "\n";
}
int main(){
	//注册信号处理函数捕获sigint中断信号，保证输出
    signal(SIGINT,sighandler);
   //构造任务
    WFHttpTask * httpTask = WFTaskFactory::create_http_task(
        "http://www.baidu.com",
        10, //最大重定向次数
        10, //最大重连次数
        httpCallback
    );
    //将任务交给框架
    httpTask->start();
    waitGroup.wait();
    cout << "finished!\n";
    return 0;
}
